/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/
/*
Authors: Ram Ovadia 201374022 and Lior Fass 300069705
Project: HW Assignment 2 
Description: This is the implementation of the utility module VS_utils.h  
*/
/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/

#include "VS_utils.h"

extern const char* serial_str = "serial";
extern const char* parallel_str = "parallel";
extern const char* txtfile_str = ".txt";

const char * folder = "Testers\\";
const char * exe_suffix = ".exe";
const char * exes[] = {"CommentHeader", "DefinesFormat", "FileNameFormat", "LineLengths"};
const char * output_strs[] = {"PASS", "FAIL", "TEST_MALFUNCTION"};
const char * timeout_str = "TIMEDOUT";

BOOL isFile(LPCTSTR path)
{
	DWORD dwAttrib = GetFileAttributes(path);
	//printf("DEBUG: in %s, in %s, input path = %s dwAttrib = %d\r\n", "VS_utils.c", "isFile", path, dwAttrib);
	
	//test that file exists, and that it is not a directory. 
	return ((dwAttrib != INVALID_FILE_ATTRIBUTES) && 
         !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}


BOOL isInteger(char *str)
{
	int i, length = 0;
	
	length = strlen(str);
	for (i=0; i < length; i++)
	{
		if ( !( (str[i] > 47) && (str[i] < 58) ) )
		{
			return FALSE;
		}
	}
	return TRUE;
}

char * BuildCommand( int exeNum,const char * line)
{
	char * command = NULL;
	command = (char *)malloc(sizeof(char)*(strlen(folder)+strlen(exes[exeNum])+strlen(exe_suffix)+strlen(line)+2)); //1 is for space, 1 for end_of_string
	strcpy(command, folder);
	strcat(command, exes[exeNum]);
	strcat(command, exe_suffix);
	strcat(command, " ");
	strcat(command, line);
	return command;
}

BOOL CreateProcessSimple( LPTSTR CommandLine, PROCESS_INFORMATION *ProcessInfoPtr )
{
	STARTUPINFO	startinfo = { sizeof( STARTUPINFO ), NULL, 0 }; /* <ISP> here we */
	/* initialize a "Neutral" STARTUPINFO variable. Supplying this to */
	/* CreateProcess() means we have no special interest in this parameter. */
	/* This is equivalent to what we are doing by supplying NULL to most other */
	/* parameters of CreateProcess(). */ 

	return CreateProcess( NULL, /*  No module name (use command line). */
		CommandLine,			/*  Command line. */
		NULL,					/*  Process handle not inheritable. */
		NULL,					/*  Thread handle not inheritable. */
		FALSE,					/*  Set handle inheritance to FALSE. */
		NORMAL_PRIORITY_CLASS,	/*  creation/priority flags. */
		NULL,					/*  Use parent's environment block. */
		NULL,					/*  Use parent's starting directory. */
		&startinfo,				/*  Pointer to STARTUPINFO structure. */
		ProcessInfoPtr			/*  Pointer to PROCESS_INFORMATION structure. */
	);
}

void StringToLower( char *pStr)
{
	for(; *pStr; ++pStr)
	{
		*pStr = tolower(*pStr);
	}
}

void finalizeRun(BOOL passFlag, FILE *hInFile, FILE *hOutFile)
{
	if (passFlag == TRUE)
	{
		fprintf(hOutFile, "The code files are ready for check-in.");
	} 
	else
	{
		fprintf(hOutFile, "The code files are not ready for check-in.");
	}

	//close files
	fclose(hInFile);
	fclose(hOutFile);
}

void closeAllHandles(PROCESS_INFORMATION ProcInfo[], int timeout_exceeded[], HANDLE lpHandles[])
{
	int i;
	for (i=0; i<NUM_OF_EXES; i++)
	{
		//close handle only if process was created. test it was actually closed. used 0 for PID in initialization since windows uses it only for idle.  
		if ( (ProcInfo[i].dwThreadId != 0 ? !CloseHandle(ProcInfo[i].hThread) : 0) ||  (ProcInfo[i].dwProcessId != 0 ? !CloseHandle(ProcInfo[i].hProcess) : 0) )
		{
			printf("failed to close handle for process: %s\r\n", exes[i]);
		}	
		timeout_exceeded[i] = 0;
		ProcInfo[i].dwProcessId = 0;
		ProcInfo[i].dwThreadId = 0;
		ProcInfo[i].hProcess = NULL;
		ProcInfo[i].hThread = NULL;
		lpHandles[i] = NULL;
	}
}

void initializeProcInfo(PROCESS_INFORMATION ProcInfo[])
{
	int i;
	for (i=0; i<NUM_OF_EXES; i++)
	{
		ProcInfo[i].dwProcessId = 0;
		ProcInfo[i].dwThreadId = 0;
		ProcInfo[i].hProcess = NULL;
		ProcInfo[i].hThread = NULL;
	}
}
